// timer.c
//

#include <avr/io.h>
#include <avr/interrupt.h>

#include "../mcu/types.h"
#include "timer.h"


#if F_CPU == 11059200

#define TCNT0_VALUE		0xD5	// interval 1ms 
								//     1 clock : 1/11059200
								//     1 ms = 1 clock * x -> x = 11059.2
                                //     43.2 on 256 prescaler(x / 256)
                                //     256 - 43 = 213 = 0xD5

#elif F_CPU == 14745600

#define TCNT0_VALUE		0x8C	// interval 1ms 
								//     1 clock : 1/14745600
								//     1 ms = 1 clock * x -> x = 14745.6
                                //     57.6 on 256 prescaler(x / 256)
                                //     256 - 58 = 198 = 0xC6

#else

	#error "timer clock undefined"

#endif

typedef struct _TIMER_ISR
{
	void (* handler)(void);

} TIMER_ISR;


static volatile u_short		tick_count;
static volatile u_short		tick_limit;
static TIMER_ISR			timer_isr;



ISR(TIMER0_OVF_vect)
{
	TCNT0 = TCNT0_VALUE;

	if( ++tick_count >= tick_limit )
	{
		tick_count = 0;

		if( timer_isr.handler )
			timer_isr.handler();
	}
}

void timer_start(u_short interval, void (* handler)(void))	// interval unit : 1ms
{
	timer_isr.handler = handler;
	tick_count = 0;
	tick_limit = interval;

	TCNT0 = TCNT0_VALUE;
	TCCR0 = 4;				// prescaler 0 : no clock source
							//           1 : clk/1
							//           2 : clk/8
							//           3 : clk/64
							//           4 : clk/256
							//           5 : clk/1024
	TIMSK |= (1 << TOIE0);
}

void timer_stop(void)
{
	TIMSK &= ~(1 << TOIE0);

//	timer_isr.handler = 0;
//	tick_count = 0;
//	tick_limit = 0;
}
